#ifndef _TBSURFACE_H_
#define _TBSURFACE_H_

#include "TBSettings.h"

#include "TBPixel.h"
#include "TBVec2.h"

namespace tb
{

	struct ShadingRectData
	{
		int x, y;
		unsigned int w, h;
	};

	typedef Pixel (*ShadingRectFunction)(ShadingRectData& a_Dst, ShadingRectData& a_Src);

	struct ShadingCircleData
	{
		Vec2 position;
		Vec2 center;
		float squared_distance;
		float squared_radius;
	};

	typedef Pixel (*ShadingCircleFunction)(ShadingRectData& a_Dst, ShadingCircleData& a_Src);

	struct ShadingLineData
	{
		Vec2 start, end;
		unsigned int step, max_step;
		float step_percentage;
		Vec2 position;
	};

	typedef Pixel (*ShadingLineFunction)(ShadingRectData& a_Dst, ShadingLineData& a_Src);

	class TB_DLL_FUNC Surface
	{
	
	public:
	
		Surface(unsigned long a_Width, unsigned long a_Height);
		Surface(unsigned long a_Width, unsigned long a_Height, Pixel* a_Data, unsigned long a_Pitch = 0);
		~Surface();

		unsigned long GetWidth() { return m_Width; }
		unsigned long GetHeight() { return m_Height; }
		unsigned long GetPitch() { return m_Pitch; }

		Pixel* GetBuffer() { return m_Data; }
		Surface& SetBuffer(Pixel* a_Data);

		Surface& Clear(Pixel a_Color);

		// ================================
		// Copying
		// ================================

		Surface& CopyTo(Surface* a_Target, int a_X, int a_Y);
		Surface& CopyPartTo(Surface* a_Target, int a_TargetX, int a_TargetY, int a_SourceX, int a_SourceY, int a_Width, int a_Height);

		Surface& DumpTo(Surface& a_Target);

		// ================================
		// Drawing
		// ================================

		Surface& Fill(Pixel a_Color);
		Surface& Fill(ShadingRectFunction a_Function);

		Surface& DrawLine(const Vec2& a_Start, const Vec2& a_End, Pixel a_Color);
		Surface& DrawLine(const Vec2& a_Start, const Vec2& a_End, ShadingLineFunction a_Function);

		Surface& DrawRect(int a_X, int a_Y, unsigned int a_Width, unsigned int a_Height, Pixel a_Color);
		Surface& DrawRect(int a_X, int a_Y, unsigned int a_Width, unsigned int a_Height, ShadingRectFunction a_Function);

		Surface& DrawCircle(const Vec2& a_Center, float a_Radius, Pixel a_Color);
		Surface& DrawCircle(const Vec2& a_Center, float a_Radius, ShadingCircleFunction a_Function);
	
	private:

		Pixel* m_Data;
		unsigned long m_Width, m_Height, m_Pitch;
	
	}; // class Surface

}; // namespace tb
	
#endif